package com.zzyl.nursing.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.zzyl.common.exception.base.BaseException;
import com.zzyl.common.utils.CodeGenerator;
import com.zzyl.nursing.domain.*;
import com.zzyl.nursing.dto.CheckInApplyDto;
import com.zzyl.nursing.dto.CheckInConfigDto;
import com.zzyl.nursing.mapper.*;
import com.zzyl.nursing.service.ICheckInService;
import com.zzyl.nursing.vo.CheckInConfigVo;
import com.zzyl.nursing.vo.CheckInDetailVo;
import com.zzyl.nursing.vo.CheckInElderVo;
import com.zzyl.nursing.vo.ElderFamilyVo;
import com.zzyl.serve.mapper.NursingLevelMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.Period;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

/**
 * 入住表Service业务层处理
 * 
 * @author zzyl
 * @date 2025-10-16
 */
@Service
public class CheckInServiceImpl extends ServiceImpl<CheckInMapper, CheckIn> implements ICheckInService
{
    @Autowired
    private CheckInMapper checkInMapper;

    @Autowired
    private ElderMapper elderMapper;

    @Autowired
    private BedMapper bedMapper;

    @Autowired
    private CheckInConfigMapper checkInConfigMapper;

    @Autowired
    private ContractMapper contractMapper;

    @Autowired
    private RoomMapper roomMapper;

    @Autowired
    private NursingLevelMapper nursingLevelMapper;

    private final Gson gson = new Gson();




    /**
     * 查询入住表
     * 
     * @param id 入住表主键
     * @return 入住表
     */
    @Override
    public CheckIn selectCheckInById(Long id)
    {
        return getById(id);
    }

    /**
     * 查询入住表列表
     * 
     * @param checkIn 入住表
     * @return 入住表
     */
    @Override
    public List<CheckIn> selectCheckInList(CheckIn checkIn)
    {
        return checkInMapper.selectCheckInList(checkIn);
    }

    /**
     * 新增入住表
     * 
     * @param checkIn 入住表
     * @return 结果
     */
    @Override
    public int insertCheckIn(CheckIn checkIn)
    {
        return save(checkIn) ? 1 : 0;
    }

    /**
     * 修改入住表
     * 
     * @param checkIn 入住表
     * @return 结果
     */
    @Override
    public int updateCheckIn(CheckIn checkIn)
    {
        return updateById(checkIn) ? 1 : 0;
    }

    /**
     * 批量删除入住表
     * 
     * @param ids 需要删除的入住表主键
     * @return 结果
     */
    @Override
    public int deleteCheckInByIds(Long[] ids)
    {
        return removeByIds(Arrays.asList(ids)) ? 1 : 0;
    }

    /**
     * 删除入住表信息
     * 
     * @param id 入住表主键
     * @return 结果
     */
    @Override
    public int deleteCheckInById(Long id)
    {
        return removeById(id) ? 1 : 0;
    }

    /**
     * 申请入住
     *
     * @param dto
     */
    @Override
    @Transactional
    public void apply(CheckInApplyDto dto) {
        Elder elder = elderMapper.selectByIdCard(dto.getCheckInElderDto().getIdCardNo());
        if (BeanUtil.isNotEmpty(elder)) {
            throw new BaseException("老人已经入住");
        }
        Bed bed = bedMapper.selectBedById(dto.getCheckInConfigDto().getBedId());
        bed.setBedStatus(1);
        bedMapper.updateById(bed);

        elder = insertOrUpdateElder(dto, bed);

        String contractNo = "HT" + CodeGenerator.generateContractNumber();

        insertContract(dto,contractNo,elder);

        CheckIn checkIn = CheckIninsert(dto, elder, bed);

        insertElderFamily(dto,checkIn);

    }

    @Override
    public CheckInDetailVo detail(Long checkInId) {
        if (checkInId == null || checkInId <= 0) {
            return null;
        }

        CheckInDetailVo detailVo = new CheckInDetailVo();

        // Step 1: 查询老人信息
        CheckInElderVo elderVo = checkInMapper.selectElderInfoByCheckInId(checkInId);
        if (elderVo == null) {
            return null; // 入住记录不存在
        }

        // 计算年龄
        if (elderVo.getBirthday() != null && !elderVo.getBirthday().isEmpty()) {
            try {
                LocalDate birthday = LocalDate.parse(elderVo.getBirthday());
                int age = Period.between(birthday, LocalDate.now()).getYears();
                elderVo.setAge(age);
            } catch (Exception e) {
                elderVo.setAge(null);
            }
        }

        detailVo.setCheckInElderVo(elderVo);

        // Step 2: 查询入住配置（费用信息）
        CheckInConfigVo configVo = checkInMapper.selectConfigInfoByCheckInId(checkInId);
        if (configVo != null) {
            detailVo.setCheckInConfigVo(configVo);
        } else {
            // 可选：创建空对象防止 NPE
            detailVo.setCheckInConfigVo(new CheckInConfigVo());
        }

        // Step 3: 查询合同信息
        Contract contract = checkInMapper.selectValidContractByElderId(elderVo.getId());
        if (contract != null) {
            detailVo.setContract(contract);
        }

        // Step 4: 解析家属 JSON
        String familyJson = checkInMapper.selectFamilyJsonByCheckInId(checkInId);
        List<ElderFamilyVo> familyList = Collections.emptyList();

        if (familyJson != null && !familyJson.trim().isEmpty()) {
            try {
                TypeToken<List<ElderFamilyVo>> typeToken = new TypeToken<List<ElderFamilyVo>>() {};
                familyList = gson.fromJson(familyJson, typeToken.getType());
            } catch (Exception e) {
                // 解析失败，返回空列表
                familyList = Collections.emptyList();
            }
        }

        detailVo.setElderFamilyVoList(familyList);
        return detailVo;
}

    private void insertElderFamily(CheckInApplyDto dto, CheckIn checkIn) {
        CheckInConfig checkInConfig = BeanUtil.toBean(dto.getCheckInConfigDto(), CheckInConfig.class);
        checkInConfig.setCheckInId(checkIn.getId());
        Integer money = roomMapper.getMoney(dto.getCheckInConfigDto().getCode());
        checkInConfig.setBedFee(BigDecimal.valueOf(money));
        checkInConfigMapper.insert(checkInConfig);
    }
    private CheckIn CheckIninsert(CheckInApplyDto dto, Elder elder, Bed bed) {

        CheckIn checkIn = BeanUtil.toBean(dto.getCheckInConfigDto(), CheckIn.class);
        checkIn.setElderId(elder.getId());
        checkIn.setElderName(elder.getName());
        checkIn.setIdCardNo(dto.getCheckInElderDto().getIdCardNo());
        checkIn.setBedNumber(bed.getBedNumber());
        checkIn.setStatus(0L);
        checkIn.setRemark(JSON.toJSONString(dto.getElderFamilyDtoList()));
        checkInMapper.insert(checkIn);
        return checkIn;
    }

    private void insertContract(CheckInApplyDto dto, String contractNo, Elder elder) {
        Contract contract = BeanUtil.toBean(dto.getCheckInContractDto(), Contract.class);
        contract.setElderId(Math.toIntExact(elder.getId()));
        contract.setContractNumber(contractNo);
        contract.setElderName(elder.getName());
        CheckInConfigDto checkInConfigDto = dto.getCheckInConfigDto();
        contract.setStartDate(checkInConfigDto.getStartDate());
        contract.setEndDate(checkInConfigDto.getEndDate());
        contract.setStatus((long) (dto.getCheckInContractDto().getSignDate().isBefore(LocalDateTime.now())?1:0));
        contract.setSignDate(dto.getCheckInContractDto().getSignDate());
        contractMapper.insert(contract);
    }

    private Elder insertOrUpdateElder(CheckInApplyDto dto ,Bed bed) {
        Elder elder = BeanUtil.toBean(dto.getCheckInElderDto(), Elder.class);
        elder.setBedId(bed.getId());
        elder.setBedNumber(bed.getBedNumber());
        elder.setStatus(1);
        elderMapper.insert(elder);
        return elder;
    }
}
